<script lang="ts" setup>
import type { StudentsApi } from '#/api/edu/base/students';

import { computed, defineEmits, ref, unref } from 'vue';

import { useVbenDrawer } from '@vben/common-ui';

import { Collapse, message } from 'ant-design-vue';

import {
  createStudents,
  getStudents,
  updateStudents,
} from '#/api/edu/base/students';
import { $t } from '#/locales';

import BasicInfo from './base-info.vue';
import OtherInfo from './other-info.vue';
import SchoolInfo from './school-info.vue';

const emit = defineEmits(['success']);
const formData = ref<StudentsApi.Students>({} as StudentsApi.Students);

const getTitle = computed(() =>
  formData.value?.studentsId
    ? $t('ui.actionTitle.edit', ['学生基本信息'])
    : $t('ui.actionTitle.create', ['学生基本信息']),
);

/** 表单引用 */
const basicInfoRef = ref<InstanceType<typeof BasicInfo>>();
const schoolInfoRef = ref<InstanceType<typeof SchoolInfo>>();
const otherInfoRef = ref<InstanceType<typeof OtherInfo>>();

const activeKeys = ref(['1', '2']); // 默认展开基础、学校

const [Drawer, drawerApi] = useVbenDrawer({
  async onConfirm() {
    const formRefs = [
      { ref: basicInfoRef, label: '基本信息', key: '1' },
      { ref: schoolInfoRef, label: '学校信息', key: '2' },
      { ref: otherInfoRef, label: '其他信息', key: '3' },
    ];

    // 校验所有表单
    for (const { ref, label, key } of formRefs) {
      if (!activeKeys.value.includes(key)) continue; // 跳过未展开
      const valid = await ref.value?.validate();
      if (!valid) {
        message.warn(`保存失败，原因：${label}表单校验失败，请检查！`);
        return;
      }
    }

    drawerApi.lock();
    try {
      // 收集表单值
      const values = await Promise.all(
        formRefs.map(({ ref }) => ref.value?.getValues() ?? {}),
      );

      const data = Object.assign({}, unref(formData), ...values);

      await (formData.value?.studentsId
        ? updateStudents(data)
        : createStudents(data));

      await drawerApi.close();
      emit('success');
      message.success($t('ui.actionMessage.operationSuccess'));
    } finally {
      drawerApi.unlock();
    }
  },

  async onOpenChange(isOpen: boolean) {
    if (!isOpen) {
      formData.value = {} as StudentsApi.Students;
      return;
    }

    let data =
      drawerApi.getData<StudentsApi.Students>() ?? ({} as StudentsApi.Students);
    if (data.studentsId) {
      drawerApi.lock();
      try {
        data = await getStudents(data.studentsId);
      } finally {
        drawerApi.unlock();
      }
    }

    formData.value = data;
  },
});
</script>

<template>
  <Drawer :title="getTitle" class="w-[80%]">
    <Collapse v-model:active-key="activeKeys">
      <Collapse.Panel key="1" header="基础信息">
        <BasicInfo ref="basicInfoRef" :students="formData" />
      </Collapse.Panel>

      <Collapse.Panel key="2" header="学校信息">
        <SchoolInfo ref="schoolInfoRef" :students="formData" />
      </Collapse.Panel>

      <Collapse.Panel key="3" header="其他信息" :destroy-inactive-panel="false">
        <OtherInfo ref="otherInfoRef" :students="formData" />
      </Collapse.Panel>
    </Collapse>
  </Drawer>
</template>
